//
//  main.m
//  08-HomeWork
//
//  Created by dllo on 16/7/13.
//  Copyright © 2016年 daming. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Person.h"
#import "Truck.h"
#import "Hero.h"
#import "NSMutableArray+Convert.h"
#import "Country.h"
int main(int argc, const char * argv[]) {
   
//    1.iOS9新特性三块的深入理解, 创建几个类, 熟悉写法(提交练习成果)
//    2.iOS 类扩展方式的复习 1> 给NSMutableArray添加convert方法，实现数组倒序。
//    3.预习UI内容
#pragma mark - Nullability(判断是否为空)
    Person *per = [[Person alloc] init];
    // nonnull 修饰的属性对应的setter和getter方法
    // nonnull修饰的属性不能为空, 所以下面的写法是错误的
//    per.name = nil;
//    [per setName:nil];
    // 正确的写法为
    NSString *objc = nil;
    per.name = objc;
    [per setName:objc];
    
    // nullable 修饰的属性对应的setter和getter方法
//    per setSex:<#(NSString * _Nullable)#>
    // 可以为空
    per.sex = nil;
    [per setSex:nil];
    
    // null_resettable(setter方法为nullable, getter方法为nonnull)
    [per setFriends:nil];
    [per friends];
    
#pragma mark - 泛型
    // 不带泛型的数组(数组中的存储类型是id类型)
    NSMutableArray *array = [NSMutableArray array];
//    array addObject:<#(nonnull id)#>
    // 带泛型数组(数组中的存储类型是NSString类型)
    NSMutableArray<NSString *> *arr = [NSMutableArray array];
//    arr addObject:<#(nonnull NSString *)#>
    // 不带泛型的字典(
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
//    dic setValue:<#(nullable id)#> forKey:<#(nonnull NSString *)#>
    // 带泛型的字典
    NSMutableDictionary<NSString *, NSString *> *dic1 = [NSMutableDictionary dictionary];
//dic1 setValue:<#(nullable NSString *)#> forKey:<#(nonnull NSString *)#>
    
    // 自定义泛型
    // 定义Person类型
    Truck<Person *> *perTruck = [[Truck alloc] init];
//    perTruck addObject:<#(Person *)#>
    // 因为Hero为Person的子类, 所以能存储该类型
    Hero *hero = [[Hero alloc] init];
//    [perTruck addObject:hero];
    
    // 协变性 与 逆变性
    Truck *truck = nil;
    Truck<NSArray *> *truck1 = nil;
    Truck<NSMutableArray *> *truck2 = nil;
    truck = truck1;
    truck = truck2;
    truck1 = truck;
    truck2 = truck;
    // __covariant 协变性: 子类在给父类赋值时, 自动强转
    // Truck<NSArray *> 与 Truck<NSMutableArray *>
    truck1 = truck2;
    // __contravariant 逆变性: 父类型可以强制转换成子类型
//    truck2 = truck1;

#pragma mark - __kindof    
    // 加__kindof修饰后返回的类型为其本类和子类
    Truck *truckKindOf = [[Truck alloc] init];
    NSMutableArray *arr2 = [truckKindOf returnArray];
    NSArray *arr1 = [truckKindOf returnArray];
    
#pragma mark -  给NSMutableArray添加convert方法，实现数组倒序。
    NSMutableArray *muArr = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", nil];
    NSMutableArray *muArr1 =[muArr convertArray];
    NSLog(@"%@", muArr1);
    
#pragma mark - 延展(Extension)
    //详见Person类
    
#pragma mark - delegate
    // 6.设定代理人
    Country *country = [[Country alloc] init];
    Hero *hero1 = [[Hero alloc] init];
    country.delegate = hero1;
    [hero1 saveEarth];
    
    return 0;
}
